package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.dto.*;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.pojo.Sku;
import com.leyou.item.pojo.Spu;
import com.leyou.item.pojo.SpuDetail;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_UP_KEY;

@Service
@Slf4j
@Transactional(propagation = Propagation.REQUIRED)
public class GoodsService {
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;
    //商品列表展示
    public PageResult<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key){
        //分页
        PageHelper.startPage(page,rows);
        //过滤
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //搜索条件
        if(StringUtils.isNoneBlank(key)){ //不是空
            criteria.andLike("name","%"+key+"%");
        }
        //上下架
        if(saleable != null){
            criteria.andEqualTo("saleable",saleable);
        }
        //按时间
        example.setOrderByClause("update_time DESC");
        //查询
        List<Spu> list = spuMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(list)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        PageInfo<Spu> pageInfo = new PageInfo<>(list);
        //封装分页
        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(list, SpuDTO.class);
        // 5 处理分类名称和品牌名称
        handleCategoryAndBrandName(spuDTOS);

        return new PageResult<>(pageInfo.getTotal(),pageInfo.getPages(),spuDTOS);
    }

    private void handleCategoryAndBrandName(List<SpuDTO> list){
        for (SpuDTO spuDTO : list) {
            //每一个spudto对象拿到 cid的集合 查称category对象 拿到name 拼上 /  收集流成字符串
            String categoryName = categoryService.queryCategoryByIds(spuDTO.getCategoryIds()).stream()
                    .map(CategoryDTO::getName).collect(Collectors.joining("/"));
//                    .map(new Function<CategoryDTO, String>() {
//                        @Override
//                        public String apply(CategoryDTO categoryDTO) {
//                            return categoryDTO.getName();
//                        }
//                    }).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(categoryName);
            BrandDTO brandDTO = brandService.queryBrandById(spuDTO.getBrandId());
            spuDTO.setBrandName(brandDTO.getName());
        }
    }

    //新增商品
    public void saveGood(SpuDTO spuDTO) {
        try {
            //存储spu
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            spu.setSaleable(false);
            spuMapper.insertSelective(spu);
            //存储sku
            List<Sku> skus = BeanHelper.copyWithCollection(spuDTO.getSkus(), Sku.class);
            for (Sku sku : skus) {
                sku.setCreateTime(new Date());
                sku.setUpdateTime(new Date());
                sku.setSpuId(spu.getId());
            }
            //insertList没有在添加sql阶段给判空 所以需要手动加上
            skuMapper.insertList(skus);
            //存储spudetail
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDTO.getSpuDetail(), SpuDetail.class);
            spuDetail.setSpuId(spu.getId());
            spuDetailMapper.insertSelective(spuDetail);
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

    }

    //商品下架
    public void updateGoodById(Long id, Boolean saleable) {
        //更新spu saleable
        Spu spu = new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if(count != 1){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
        //发送mq消息 上架和下架
        String key = saleable ? ITEM_UP_KEY : ITEM_DOWN_KEY;
        amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,key,id);
//        //更新sku
//        Sku sku = new Sku();
//        sku.setEnable(saleable);
//        Example example = new Example(Sku.class);
//        Example.Criteria criteria = example.createCriteria();
//        criteria.andEqualTo("spuId",id);
//        //根据spu_id更新 返回结果看有多少个被更新了
//        count = skuMapper.updateByExampleSelective(sku, example);
//        //查询spu_id为 id 的有多少个
//        int i = skuMapper.selectCountByExample(example);
//        if(count != i){
//            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
//        }

    }

    //回显商品详情数据spuDetail
    public SpuDetailDTO findSpuDetailById(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);
        if(spuDetail == null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail,SpuDetailDTO.class);
    }

    //通过SpuId查询 商品的sku
    public List<SkuDTO> findSkuById(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> list = skuMapper.select(sku);
        if(CollectionUtils.isEmpty(list)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(list,SkuDTO.class);
    }

    //修改商品
    public void updateGood(SpuDTO spuDTO) {
        try{
            //先转换成POJO
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            //修改spu数据
            spuMapper.updateByPrimaryKeySelective(spu);
            //得到spuDetail
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
            //修改spudtail
            spuDetailMapper.updateByPrimaryKeySelective(spuDetail);

            //删除sku
            Sku sku = new Sku();
            sku.setSpuId(spu.getId());
            skuMapper.delete(sku);
            //得到sku 可能删除可能修改可能新增   直接先删除再新增
            List<SkuDTO> skus = spuDTO.getSkus();
            List<Sku> list = BeanHelper.copyWithCollection(skus, Sku.class);
            for (Sku  sku1: list) {
//                sku1.setCreateTime(new Date());
//                sku1.setUpdateTime(new Date());
                sku1.setSpuId(spu.getId());
            }
            //insertList没有在添加sql阶段给判空 所以需要手动加上
            skuMapper.insertList(list);
        }catch (Exception e){
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    //通过spuId查询 spuDTO
    public SpuDTO findSpuBySpuId(Long spuId){
        try {
            Spu spu = spuMapper.selectByPrimaryKey(spuId);
            SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);

            List<SkuDTO> skuDTOS = findSkuById(spuId);
            spuDTO.setSkus(skuDTOS);

            SpuDetailDTO spuDetailDTO = findSpuDetailById(spuId);
            spuDTO.setSpuDetail(spuDetailDTO);
            return spuDTO;
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
    }

    //生成订单的时候 前端传回的数据skuid 需要合并所有id查出 sku详情中的金额
    //查询购物车 未登录的 用于展示 购物车页面的数据
    public List<SkuDTO> findSkusBySkuIds(List<Long> ids) {
        List<Sku> skus = skuMapper.selectByIdList(ids);
        if(CollectionUtils.isEmpty(skus)){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(skus,SkuDTO.class);

    }

    //减少库存   map skuid 数量
    public void minusStock(Map<Long, Integer> map) {
        try {
            map.entrySet().forEach(entry ->{
                //获取skuid
                Long skuId = entry.getKey();
                //获取数量
                Integer number = entry.getValue();
                //查询当前sku
                Sku sku = skuMapper.selectByPrimaryKey(skuId);
                //修改
                Sku sk = new Sku();
                sk.setId(skuId);
                sk.setStock(sku.getStock() - number);
                skuMapper.updateByPrimaryKeySelective(sk);
                //这里不需要判断 库存比需要删除的数量还少的问题
                //在数据库 有unsign修饰stock字段 恒非负数
            });
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }
}
